package it.low.game.client;

import java.awt.Point;

import it.low.game.client.gui.ClientScreen;
import it.low.game.client.server.ClientServerInterface;
import it.low.game.client.server.ClientServerInterfaceImpl;
import it.low.game.client.settings.GraphicSetting;
import it.low.game.client.util.ClientLogManager;
import it.low.game.server.Server;
import it.low.util.Constant;

public class GameClient {
	
	public static final int CLIENT_ID = 1;
	private static boolean running = false;
	
	public static final int VIEW_WIDTH = 1200;
	public static final int VIEW_HEIGHT = 600;	
	public static final int HALF_VIEW_WIDTH = VIEW_WIDTH/2;
	public static final int HALF_VIEW_HEIGHT = VIEW_HEIGHT/2;
	
	private static ClientScreen clientScreen = null;
	private static GameSession gameSession = null;
	private static ClientServerInterface clientServerInterface = null;
		
	public static void main(String args[]){
		ClientLogManager.logMsg("**** START CLIENT ID = "+CLIENT_ID+"****");		
		try{
			Server.init(); // INIT DEL SERVER SIMULATO PRIMA DEL CLIENT
			Server.start(); // START DEL SERVER SIMULATO PRIMA DEL CLIENT
			init();
			start();						
		}finally{
		}		
	}
	
	private static void init(){
		ClientLogManager.logMsg("call GameClient.init()");		
		initGameGui();
		initGameNetwork();
		initGameSession(); // DA DELEGARE AD UN COMANDO
	}
	
	private static void start(){
		ClientLogManager.logMsg("call GameClient.start()");
		startGameSession(); // DA DELEGARE AD UN COMANDO
		running = true;		
		try {			 
			 loop();
	     }
		 finally {
			 //stop();
			 exit();
	     }		
	}
	
	private static void initGameGui(){
		ClientLogManager.logMsg("call GameClient.initGameGui()");
		
		if(loadGraphicSetting()){
			GraphicSetting.width = 0;
			GraphicSetting.height = 0;
			GraphicSetting.bitDepth = 0;
		}		
		
		clientScreen = new ClientScreen(GraphicSetting.width,GraphicSetting.height,GraphicSetting.bitDepth);
		clientScreen.init(new Point(10,10));
	}
	
	private static boolean loadGraphicSetting(){
		ClientLogManager.logMsg("call GameClient.loadGraphicSetting()");
		ClientLogManager.logMsg("exit GameClient.loadGraphicSetting() return false");
		return false;
	}
	
	private static int initGameNetwork(){
		int networkInitStatus = Constant.GENERIC_OK;
		clientServerInterface = new ClientServerInterfaceImpl();
		//clientServerInterface = new ClientServerNetworking();
		networkInitStatus = clientServerInterface.init(CLIENT_ID);
		return networkInitStatus;
	}
	
	private static int initGameSession(){
		ClientLogManager.logMsg("call GameClient.initGameSession()");
		int clientInitStatus = Constant.GENERIC_OK;
		gameSession = new GameSession(clientServerInterface);
		clientInitStatus = gameSession.init(CLIENT_ID);
		return clientInitStatus;
	}
	
	 public static void startGameSession(){
		 ClientLogManager.logMsg("call GameClient.startGameSession()");
		 gameSession.start();
	 }
	
	public static GameSession getGameSession(){
		return gameSession;
	}
	
	 public static void stop(){
		 ClientLogManager.logMsg("call GameClient.stop()");
		 running = false;
		 if(gameSession!=null && gameSession.isRunning()){
			 gameSession.stop();
		 }
	 }
	
	public static void exit(){
		ClientLogManager.logMsg("call GameClient.exit()");
		gameSession = null;
		if(clientServerInterface!=null){
			clientServerInterface.close(CLIENT_ID);
			clientServerInterface = null;
		}
		if(clientScreen!=null){
			clientScreen.close();
			clientScreen = null;
		}
		ClientLogManager.logMsg("**** EXIT CLIENT ****");
	}
	
	public static void loop(){
		ClientLogManager.logMsg("call GameClient.loop()");
        long startTime = System.currentTimeMillis();
        long currTime = startTime;

        //ClientLogManager.logMsg("call GameClient.loop() GameClient.running = "+running);
        //ClientLogManager.logMsg("call GameClient.loop() this.running = "+gameSession.isRunning());

        while (running) {
            long elapsedTime = System.currentTimeMillis() - currTime;
            currTime += elapsedTime;
            
            clientServerInterface.receiveWorldState(elapsedTime); // UPDATE DEL SERVER SIMULATO PRIMA DEL CLIENT
            
            if(gameSession!=null /*&& gameSession.isRunning()*/){            	
	            gameSession.update(elapsedTime); // ?? TO DO OR NOT 
	            clientScreen.gamePanel.repaint();	            
            }else{
            	clientScreen.gamePanel.repaint();
            }            
            
            try {
                Thread.sleep(5);
            }
            catch (InterruptedException ex) { }
        }
    } 
	
}
